package com.zj.weather.utils;

import android.graphics.Path;
import android.graphics.PathMeasure;
import android.os.Build;

import java.util.ArrayList;
import java.util.List;

import static android.os.Build.VERSION_CODES.KITKAT;

/**
 * Created by ZhaoJie on 2018/8/5.
 */

public class PathAliasChangeUtils {

    /**
     * 获取一段Path 的平滑渐变集合
     *
     * @param start       0.0f-1.0f start < end;
     * @param end         0.1f -1.0f;
     * @param isFromStart 是否从start开始渐变，还是从end渐变到start
     * @param changePath  参与渐变的路径
     * @param duration    0.0f -1.0f 平滑度，值越小转变越平滑，但是效率越低；
     * @return PathClipInfo.surplusPath:经过处理后剩余的未改变的Path
     */

    public static PathClipInfo getAliasPathClip(float start, float end, float duration, float maxWidth, float minWidth, @SuppressWarnings("SameParameterValue") boolean isFromStart, Path changePath) {
        if (start >= end)
            throw new IllegalStateException("clip length with 'start' should bigger than end!");
        if (start > 1f || end > 1f)
            throw new NullPointerException("start & end must to <= 1.0f, length * (? > 1.0f) was not point");
        PathMeasure pathMeasure = new PathMeasure(changePath, false);
        Path path = new Path();
        Path surplusPath = new Path();
        if (Build.VERSION.SDK_INT <= KITKAT) {
            path.lineTo(0, 0);
            surplusPath.lineTo(0, 0);
        }
        float length = pathMeasure.getLength();
        float startLength = start * length;
        float endLength = end * length;
        pathMeasure.getSegment(startLength, endLength, path, true);
        boolean isAllChange = startLength == 0 && endLength == length;
        if (!isAllChange) {
            if (startLength == 0 || endLength == length) {
                float surplusStart, surplusEnd;
                if (startLength == 0) {
                    surplusStart = length - endLength;
                    surplusEnd = length;
                } else {
                    surplusStart = 0;
                    surplusEnd = startLength;
                }
                pathMeasure.getSegment(surplusStart, surplusEnd, surplusPath, true);
            } else
                throw new IllegalStateException("The intercepted path from the middle is unsupported!");
        }
        PathClipInfo resultInfo = new PathClipInfo();
        resultInfo.maxWidth = maxWidth;
        resultInfo.minWidth = minWidth;
        resultInfo.surplusPath = surplusPath;
        resultInfo.pathChanges = new ArrayList<>();
        float curDuration = 0.0f;
        PathMeasure measure = new PathMeasure(path, false);
        float pathLength = measure.getLength();
        float maxChangeNum = maxWidth - minWidth;
        while (curDuration < pathLength) {
            PathChangeInfo info = new PathChangeInfo();
            info.oldDuration = curDuration;
            curDuration = Math.min(pathLength, info.oldDuration + (duration * pathLength));
            info.curDuration = curDuration;
            float fraction = info.curDuration / pathLength;
            if (isFromStart)
                info.width = fraction * maxChangeNum + minWidth;
            else
                info.width = maxWidth - fraction * maxChangeNum;
            measure.getSegment(info.oldDuration, info.curDuration, info.path, true);
            resultInfo.pathChanges.add(info);
        }
        return resultInfo;
    }

    public static class PathClipInfo {
        public List<PathChangeInfo> pathChanges;
        public Path surplusPath;
        public float maxWidth;
        public float minWidth;
    }

    public static class PathChangeInfo {
        public Path path;
        public float curDuration;
        public float oldDuration;
        public float width;

        public PathChangeInfo() {
            path = new Path();
            if (Build.VERSION.SDK_INT <= KITKAT)
                path.lineTo(0, 0);
        }

        @Override
        public String toString() {
            return "  path = " + path + "  width = " + width + "  curD = " + curDuration + "   oldD = " + oldDuration;
        }
    }

}
